'''
Author: 蚢
Date: 2021-05-12 14:16:04
Description: 文件与IO
'''
from functools import partial
import bz2
import gzip
import io
import sys

####### 1.读写文本数据 #######
# note: 读: rt;   写: wt;   追加:at
# note: 读: rb;   写: wb;   追加:ab
# 不存在时写入,可以防止覆盖: xt/xb

with open('file.txt', 'rt') as f:
    data = f.read()

# 查看读写时的系统编码
my_encoding = sys.getdefaultencoding()
print(my_encoding)

# 指定编码方式 : 常见的编码是ascii, latin-1, utf-8和utf-16
with open('file.txt', 'rt', encoding='latin-1') as f:
    data = f.read()

''' 1.当读取一个未知编码的文本时使用latin-1编码永远不会产生解码错误 '''
''' 2.使用with语句文件会自动关闭,不使用则需要加: f.close() '''
''' 3.python在处理时会默认把换行符转换为 \n 但windows下应为 \r\n, 传入
    newline='' 就不会默认转换. '''
with open('file.txt', 'rt', newline='') as f:
    pass

# error参数可以忽略未知编码的错误:但是不建议.
with open('file.txt', 'rt', errors='ignore') as f:
    pass

###### 2.打印输出到文件中 #######
# 文件打开方式必须为文本模式, 不能是二进制.
with open('file.txt', 'wt') as f:
    print('hello world', file=f)

###### 3.使用其他分隔符或行终止符打印 #######
# 使用sep,和 end关键字可以控制输出分隔符和终止符
print('A', 1, 2, sep='--')
print('a', 1, 2, end='->this is end')
# 分隔符问题,也可以用str.join()实现,但join()仅适用于字符串
string = ('a', 'b', 'c')
','.join(string)

###### 4.读写字节数据 #######
# note:由于读取的是字节数据, 输出时为字节值
# 从二进制文件中读写文件需要编解码
with open('file.bin' 'rb') as f:
    data = f.read()
    text = data.decode('utf-8')

###### 6.字符串的I/O操作 #######
# 可以将字符串看成文件进行I.O操作
# 使用io.StringIO() 和 io.BytesIO()
s = io.StringIO()
s.write('this is str file')
s.getvalue()
print(' add some str', file=s)
s.read()
b = io.BytesIO()
b.write(b'hello world')
b.read()

###### 7.读写压缩文件 #######
# gzip 和 bz2 模块有相应的open()
# compresslevel 指定压缩等级:0~9,
# note: 可以作用在已打开的文件上
with gzip.open('file.gz', 'rt') as f:
    data = f.read()

with bz2.open('file.bz3', 'rt') as f:
    data = f.read()

f = open('file.txt', 'rt')
with gzip.open(f, 'rt') as g:
    pass
f.close()

###### 8.固定大小记录的文件迭代 #######

RECORD_SIZE = 32

with open('somefile.data', 'rb') as f:
    records = iter(partial(f.read, RECORD_SIZE), b'')

    for r in records:
        ...

 